package com.lyw.ioc;

import com.lyw.ioc.component.UserComponent;
import com.lyw.ioc.configuration.UserConfiguration;
import com.lyw.ioc.controller.HelloController;
import com.lyw.ioc.model.Student;
import com.lyw.ioc.repository.UserRepository;
import com.lyw.ioc.service.UserService;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;

@SpringBootApplication
public class SpringIocDemoApplication {

    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(SpringIocDemoApplication.class, args);

        // 从IoC容器中获取bean 三种方法 通过类型（by Type）获取 适合该类型的对象只有一个
        HelloController bean1 = context.getBean(HelloController.class);
        bean1.print();

        // Bean 的名称（by Name）spring默认创建的bean名称为类名首字母小写(小驼峰)
        //HelloController bean2 = (HelloController) context.getBean("helloController");
        HelloController bean2 = (HelloController) context.getBean("hello");//修改bean的名称，默认是小驼峰
        bean2.print();

        //（名称 + 类型） 的方式获取 Bean, 当容器中存在多个同类型的 Bean，但你需要 明确指定其中一个
        //HelloController bean3 = context.getBean("helloController", HelloController.class);
        HelloController bean3 = context.getBean("hello", HelloController.class);
        bean3.print();

        //上述三个bean，获取同一个对象
        System.out.println(bean1);
        System.out.println(bean2);
        System.out.println(bean3);

        //bean4-7都是从容器中获取的, 不是同一个注解添加进去的 本质都是Component, 其他两种获取方法同上一样
        //五大注解分别为@Controller(控制层), @Service(业务逻辑层), @Repository(数据层), @Configuration(配置曾),@Component(组件层)
        //控制层必须为controller, controller不光是将类交给IOC容器, 还负责客户端的请求交互
        UserService bean4 = context.getBean(UserService.class);
        bean4.print();

        UserRepository bean5 = context.getBean(UserRepository.class);
        bean5.print();

        UserComponent bean6 = context.getBean(UserComponent.class);
        bean6.print();

        UserConfiguration bean7 = context.getBean(UserConfiguration.class);
        bean7.print();

        //用Bean方法注解将类放到容器中, 能放入多个同一个类型的bean的不同实例, 默认名字是方法名
        Student bean8 = (Student) context.getBean("s1");
        System.out.println(bean8);

        Student bean9 = (Student) context.getBean("s2");
        System.out.println(bean9);

        //修改bean的名称
        Student bean10 = (Student) context.getBean("wangwu");
        System.out.println(bean10);

        //bean修饰方法传参
        Student bean11 = (Student) context.getBean("s4");
        System.out.println(bean11);

        //DI注入测试
        HelloController bean12 = context.getBean(HelloController.class);
        bean12.print();

        UserService bean13 = context.getBean(UserService.class);
        bean13.print();
    }

}
